/**
 * 图形类定义----提供Graphic及其子类对象的配置参数
 */
/**
 * 图形父类
 */
class Graphic {
  //properties-抽取公共属性
  id = null
  name = 'Graphic'
  show = true
  position = null
  properties = null
  //getter

  //setter

  //constructors
  constructor(options = {}) {
    const {
      id = Cesium.createGuid(), //id-unique
      name = Graphic.name, //name-un_unique
      show = true, //show
      position, //PositionProperty|Cartesian3
      properties = Object.create(null), //properties-Object
    } = options
    this.id = id
    this.name = name
    this.show = show
    this.position = position
    this.properties = properties
  }
}

//point
class Point extends Graphic {
  //properties-Point扩展属性
  point = {
    pixelSize: 5,
    heightReference: Cesium.HeightReference.NONE,
    color: Cesium.Color.RED,
    outlineColor: Cesium.Color.BLACK,
    outlineWidth: 1,
    disableDepthTestDistance: Number.NEGATIVE_INFINITY,
  }

  //constructor
  constructor(options = {}) {
    super(options)
    this.name = "point";
    //options解构
    const {
      pixelSize = 1,
      heightReference = Cesium.HeightReference.NONE,
      color = Cesium.Color.WHITE,
      outlineColor = Cesium.Color.BLACK,
      outlineWidth = 1,
      disableDepthTestDistance = Number.NEGATIVE_INFINITY,
    } = options
    this.point.pixelSize = pixelSize
    this.point.heightReference = heightReference
    this.point.color = color
    this.point.outlineColor = outlineColor
    this.point.outlineWidth = outlineWidth
    this.point.disableDepthTestDistance = disableDepthTestDistance
  }
}

//Label
class Label extends Graphic {
  //properties-Label扩展属性
  label = {
    text: new Cesium.CallbackProperty(function () {
      return ''
    }, false),
    font: '24px sans-serif',
    style: Cesium.LabelStyle.FILL,
    scale: 1.0,
    showBackground: true,
    backgroundColor: new Cesium.Color(0.165, 0.165, 0.165, 0.8),
    pixelOffset: Cesium.Cartesian2.ZERO,
    eyeOffset: Cesium.Cartesian3.ZERO,
    horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
    verticalOrigin: Cesium.VerticalOrigin.CENTER,
    heightReference: Cesium.HeightReference.NONE,
    fillColor: Cesium.Color.WHITE,
    outlineColor: Cesium.Color.BLACK,
    outlineWidth: 1,
    disableDepthTestDistance: Number.NEGATIVE_INFINITY,
  }
  //constructor
  constructor(options = {}) {
    super(options)
    this.name = "label";
    //options解构
    const {
      text = new Cesium.CallbackProperty(function () {
        return ''
      }, false),
      font = '24px sans-serif',
      style = Cesium.LabelStyle.FILL,
      scale = 1.0,
      showBackground = true,
      backgroundColor = new Cesium.Color(0.165, 0.165, 0.165, 0.8),
      pixelOffset = Cesium.Cartesian2.ZERO,
      eyeOffset = Cesium.Cartesian3.ZERO,
      horizontalOrigin = Cesium.HorizontalOrigin.CENTER,
      verticalOrigin = Cesium.VerticalOrigin.CENTER,
      heightReference = Cesium.HeightReference.NONE,
      fillColor = Cesium.Color.WHITE,
      outlineColor = Cesium.Color.BLACK,
      outlineWidth = 1,
      disableDepthTestDistance = Number.NEGATIVE_INFINITY,
    } = options
    this.label.text = text
    this.label.font = font
    this.label.style = style
    this.label.scale = scale
    this.label.showBackground = showBackground
    this.label.backgroundColor = backgroundColor
    this.label.pixelOffset = pixelOffset
    this.label.eyeOffset = eyeOffset
    this.label.horizontalOrigin = horizontalOrigin
    this.label.verticalOrigin = verticalOrigin
    this.label.fillColor = fillColor
    this.label.heightReference = heightReference
    this.label.outlineColor = outlineColor
    this.label.outlineWidth = outlineWidth
    this.label.disableDepthTestDistance = disableDepthTestDistance
  }
}

//Polyline
class Polyline extends Graphic {
  //properties-Polyline拓展属性
  linePositions = new Array()
  polyline = null

  //constructor
  constructor(options = {}) {
    super(options)
    this.name = "polyline";
    const self = this
    const { width = 1.0, material = Cesium.Color.WHITE } = options
    this.polyline = {
      positions: new Cesium.CallbackProperty(function () {
        return self.linePositions
      }),
      width: width,
      granularity: Cesium.Math.RADIANS_PER_DEGREE,
      material: material,
      arcType: Cesium.ArcType.GEODESIC,
      clampToGround: false, //贴地线-建议为false;设置为true之后,画线时会进行额外的计算,极其卡顿
      shadows: Cesium.ShadowMode.DISABLED, //阴影
      classificationType: Cesium.ClassificationType.BOTH,
      zIndex: 0,
    }
  }

  //更新polyline的坐标点
  updatePositions(cartesian3) {
    this.linePositions.push(cartesian3)
  }
}

//Polygon
class Polygon extends Graphic {
  //polygon坐标串---通过该属性拿到坐标数据
  polygonPositions = new Array()
  polygon = null

  constructor(options = {}) {
    super(options)
    this.name = "polygon";
    const self = this
    //参数解构
    const {
      fill = true,
      material = Cesium.Color.RED.withAlpha(0.5),
      outline = true,
      outlineColor = Cesium.Color.WHITE,
      outlineWidth = 1.0,
    } = options
    //创建polygon
    this.polygon = {
      hierarchy: new Cesium.CallbackProperty(function () {
        return new Cesium.PolygonHierarchy(self.polygonPositions)
      }),
      height: 0,
      heightReference: Cesium.HeightReference.NONE,
      fill: fill,
      material: material,
      outline: outline,
      outlineColor: outlineColor,
      outlineWidth: outlineWidth,
      classificationType: Cesium.ClassificationType.BOTH,
    }
  }

  updatePositions = (cartesian3) => {
    this.polygonPositions.push(cartesian3)
  }
}

//Rectangle
class Rectangle extends Graphic {
  rectanglePositions = new Array()
  rectangle = null

  constructor(options = {}) {
    super(options)
    this.name = "rectangle";
    const { material = Cesium.Color.RED.withAlpha(0.5) } = options //配置项解构
    this.rectangle = {
      //坐标点位
      coordinates: new Cesium.CallbackProperty(function () {
        return new Cesium.Rectangle()
      }),
      fill: true, //是否填充
      material: material, //填充色
    }
  }

  //更新坐标
  updatePositions(cartesian3){
    if(this.rectanglePositions.length>1){
      this.rectanglePositions.pop();
    }
    this.rectanglePositions.push(cartesian3);//添加新的坐标点
  }
  

  //根据坐标序列更新Entity的矩形范围
  updateRectangleByPositions(cartesian3,entity){
    const self = this;
    this.updatePositions(cartesian3);
    //更新矩形范围
    entity.rectangle.coordinates = new Cesium.CallbackProperty(function () {
      return Cesium.Rectangle.fromCartesianArray(self.rectanglePositions);
    },false)
  }
}
